//
//  SEUploadViewModel.swift
//  SmartEyeForPatient
//
//  Created by QDSG on 2021/4/23.
//

import UIKit

class SEUploadViewModel: SEBaseViewModel {
    
    var fileModel: SEUploadFileModel?
    
    private var uploadImageUrl: String = ""
    private var resourceId: String = ""
    
    private var status: SEHttpStatus = .success
    
    func uploadImage(bucket: String, type: String, image: UIImage, relationId: String = "", introduction: String = "image/png", size: Double, systemId: Int = 3, checkStatus: Int = 0, isIm: Int = 0) {
        
        let semaphore = DispatchSemaphore(value: 1)
        let uploadFileQueue = DispatchQueue(label: "uploadFileQueue")
        let uploadFileGroup = DispatchGroup()
        
        let imageData = image.jpegData(compressionQuality: 1) ?? Data()
        
        uploadFileGroup.enter()
        uploadFileQueue.async {
            semaphore.wait() // 让信号量-1，比如默认值时0，wait()以后就变成了－1，因此会等待
            self.getPresignedUrl(bucket: bucket) { success in
                if success {
                    semaphore.signal() // 让信号量+1，当>0时就代表绿灯可以走了
                } else {
                    uploadFileGroup.leave()
                }
            }
            
            semaphore.wait()
            self.uploadFileToS3(imageData) { success in
                if success {
                    semaphore.signal()
                } else {
                    uploadFileGroup.leave()
                }
            }
            
            semaphore.wait()
            self.saveFileToDataBase(bucket: bucket, type: type, imageData: imageData, relationId: relationId, introduction: introduction, size: size, systemId: systemId, checkStatus: checkStatus, isIm: isIm) {
                semaphore.signal()
                uploadFileGroup.leave()
            }
        }
        
        uploadFileGroup.notify(queue: DispatchQueue.main) {
            self.updateData?(self.status)
        }
    }
    
    private func getPresignedUrl(bucket: String, finished: @escaping (Bool) -> Void) {
        SELog("getPresignedUrl--")
        SEHttpManager.shared.request(SEUploadAPI.getPresignedUrlForUploadFile(bucket: bucket), model: String.self, completion: { (uploadUrl, httpStatus) in
            self.status = httpStatus
            switch httpStatus {
            case .success:
                self.uploadImageUrl = uploadUrl ?? ""
                SELog("uploadImageUrl = \(self.uploadImageUrl)")
                finished(true)
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
                finished(false)
            }
        })
    }
    
    private func uploadFileToS3(_ imageData: Data, finished: @escaping (Bool) -> Void) {
        SELog("uploadFileToS3++")
        guard let url = URL(string: uploadImageUrl) else {
            self.status = .failure("上传文件出小差了~")
            finished(false)
            return
        }
        
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = "PUT"
        urlRequest.httpBody = imageData

        SEHUD.showActivity()
        let dataTask = URLSession.shared.dataTask(with: urlRequest) { (data, response, error) in
            SEHUD.hideActivity()
            if error != nil {
                self.status = .failure(error?.localizedDescription)
                SELog("通过 Presigned Url 上传图片 error: \(error.debugDescription)")
                self.resourceId = ""
                finished(false)
            } else {
                SELog("通过 Presigned Url 上传图片 response: \(String(describing: response))")
                self.status = .success
                self.resourceId = self.uploadImageUrl.components(separatedBy: "?").first?.components(separatedBy: "/").last ?? ""
                finished(true)
            }
        }
        dataTask.resume()
    }
    
    private func saveFileToDataBase(bucket: String, type: String, imageData: Data, relationId: String, introduction: String, size: Double, systemId: Int, checkStatus: Int, isIm: Int, finished: @escaping () -> Void) {
        SELog("saveFileToDataBase==")
        SEHttpManager.shared.request(SEUploadAPI.insertDBAfterUploadFile(bucket: bucket, type: type, relationId: relationId, introduction: introduction, size: size, url: resourceId, systemId: systemId, checkStatus: checkStatus, remarks: "", isIm: isIm), model: SEUploadFileModel.self, withLoading: withLoading) { (model, httpStatus) in
            self.status = httpStatus
            switch httpStatus {
            case .success:
                self.fileModel = model
                self.fileModel?.imageData = imageData
            case .auth(let message), .failure(let message):
                SEHUD.showError(message: message)
            }
            finished()
        }
    }
}
